﻿using SBlogCore.Common.RemoteRequest.Extensions;
using System.Text;
using System.Text.Json;

namespace SBlogCore.Common.RemoteRequest.Models
{
    [SkipScan]
    public class HttpClientPart
    {
        private IHttpClientFactory httpClientFactory;
        public HttpClientPart(IHttpClientFactory _httpClientFactory)
        {
            httpClientFactory = _httpClientFactory;
        }
        /// <summary>
        /// 链接名称
        /// </summary>
        private string? clientName;
        public HttpClientPart SetClientName(string value)
        {
            this.clientName = value;
            return this;
        }
        /// <summary>
        /// 请求头
        /// </summary>
        private IDictionary<string, object>? headers;
        public HttpClientPart SetHeaders(IDictionary<string, object> value)
        {
            this.headers = value;
            return this;
        }
        /// <summary>
        /// 查询参数
        /// </summary>
        private IDictionary<string, object>? queries;
        public HttpClientPart SetQueries(IDictionary<string, object> value)
        {
            this.queries = value;
            return this;
        }
        /// <summary>
        /// 超时时间
        /// </summary>
        private int timeoutSecond=60;
        public HttpClientPart SetTimeoutSecond(int value)
        {
            this.timeoutSecond = value;
            return this;
        }
        /// <summary>
        /// 请求方式
        /// </summary>
        private HttpMethod? method;
        public HttpClientPart SetMethod(HttpMethod value)
        {
            this.method = value;
            return this;
        }
        /// <summary>
        /// 请求Uri
        /// </summary>
        private string? requestUri;
        public HttpClientPart SetRequestUri(string value)
        {
            this.requestUri = value;
            return this;
        }
        /// <summary>
        /// 内容
        /// </summary>
        private object? body;
        public HttpClientPart SetBody(object value)
        {
            this.body = value;
            return this;
        }
        /// <summary>
        /// 编码
        /// </summary>
        private Encoding encoding = Encoding.UTF8;
        public HttpClientPart SetEncoding(Encoding value)
        {
            encoding = value;
            return this;
        }
        /// <summary>
        /// 内容类型
        /// </summary>
        private string ContentType = "application/json";
        public HttpClientPart SetContentType(string value)
        {
            ContentType = value;
            return this;
        }
        private HttpClient BuildHttpClient()
        {
            HttpClient client;
            if (!string.IsNullOrEmpty(clientName))
            {
                client = httpClientFactory.CreateClient(clientName);
            }
            else {
                client = httpClientFactory.CreateClient();
            }
            client.DefaultRequestHeaders.Clear();
            client.DefaultRequestHeaders.Add("Accept", ContentType);
            client.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
            if (headers!=null)
            {
                foreach (var header in headers)
                {
                    if (!client.DefaultRequestHeaders.Contains(header.Key))
                    {
                        client.DefaultRequestHeaders.Add(header.Key, header.ToString());
                    }
                }
            }
            client.Timeout = TimeSpan.FromSeconds(timeoutSecond);
            return client;
        }
        /// <summary>
        /// 创建请求体
        /// </summary>
        /// <returns></returns>
        private HttpRequestMessage BuildRequestMessage()
        {
            if (method==null)
            {
                throw new Exception("请求方式不明确！");
            }
            var  requestMessage = new HttpRequestMessage(method, requestUri);
            SetHttpRequestMessageBody(requestMessage);
            return requestMessage;
        }
        /// <summary>
        /// 设置BODY
        /// </summary>
        /// <param name="request"></param>
        private void SetHttpRequestMessageBody(HttpRequestMessage request)
        {
            if (body == null || method == HttpMethod.Get || method == HttpMethod.Head) return;
            request.Content = new StringContent(BodySerialize(), encoding, ContentType);
        }
        /// <summary>
        /// BODY序列化
        /// </summary>
        /// <returns></returns>
        private string BodySerialize()
        {
            if (body!=null&&body is string)
            {
                return body.ToString()!;
            }
            var result= JsonSerializer.Serialize(body);
            return result;
        }

        /// <summary>
        /// 异步发送
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<T?> SendAsync<T>()
        {
            HttpClient? client = BuildHttpClient();
            OnHttpClientFilter(client);
            HttpRequestMessage? requestMessage = BuildRequestMessage();
            if (queries!=null)
            {
                requestMessage.AppendQueries(queries);
            }
            OnRequestFilter(requestMessage);
            HttpResponseMessage? response = await client.SendAsync(requestMessage);
            OnResponseFilter(response);
            var responseContent = await response.Content.ReadAsStringAsync();
            if (response.IsSuccessStatusCode)
            {
                //大小写不敏感
                var Property = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true };
                var result = JsonSerializer.Deserialize<T>(responseContent, Property);
                return result;
            }
            else
            {
                OnExceptionFilter(response);
                throw new Exception(response.StatusCode.ToString());
            }
        }

        #region 拦截过滤
        /// <summary>
        /// 创建连接拦截
        /// </summary>
        private List<Action<HttpClient>>? onHttpClientList;
        public void SetOnHttpClient(Action<HttpClient> action)
        {
            if (onHttpClientList == null)
            {
                onHttpClientList = new List<Action<HttpClient>>();
            }
            if (!onHttpClientList.Contains(action))
            {
                onHttpClientList.Add(action);
            }
        }
        /// <summary>
        /// 请求拦截
        /// </summary>
        private List<Action<HttpRequestMessage>>? onRequestingList;
        public void SetOnRequesting(Action<HttpRequestMessage> action)
        {
            if (onRequestingList == null)
            {
                onRequestingList = new List<Action<HttpRequestMessage>>();
            }
            if (!onRequestingList.Contains(action))
            {
                onRequestingList.Add(action);
            }
        }
        /// <summary>
        /// 响应拦截
        /// </summary>
        private List<Action<HttpResponseMessage>>? onResponsingList;
        public void SetOnResponsing(Action<HttpResponseMessage> action)
        {
            if (onResponsingList == null)
            {
                onResponsingList = new List<Action<HttpResponseMessage>>();
            }
            if (!onResponsingList.Contains(action))
            {
                onResponsingList.Add(action);
            }
        }
        /// <summary>
        /// 异常拦截
        /// </summary>
        private List<Action<HttpResponseMessage>>? onExceptionList;
        public void SetOnException(Action<HttpResponseMessage> action)
        {
            if (onExceptionList == null)
            {
                onExceptionList = new List<Action<HttpResponseMessage>>();
            }
            if (!onExceptionList.Contains(action))
            {
                onExceptionList.Add(action);
            }
        }
        /// <summary>
        /// 异常过滤
        /// </summary>
        /// <param name="response"></param>
        private void OnExceptionFilter(HttpResponseMessage response)
        {
            foreach (var onException in onExceptionList ?? new List<Action<HttpResponseMessage>>())
            {
                onException(response);
            }
        }
        /// <summary>
        /// 响应过滤
        /// </summary>
        /// <param name="response"></param>
        private void OnResponseFilter(HttpResponseMessage response)
        {
            foreach (var onResponsing in onResponsingList ?? new List<Action<HttpResponseMessage>>())
            {
                onResponsing(response);
            }
        }
        /// <summary>
        /// 请求过滤
        /// </summary>
        /// <param name="requestMessage"></param>
        private void OnRequestFilter(HttpRequestMessage requestMessage)
        {
            foreach (var onRequesting in onRequestingList ?? new List<Action<HttpRequestMessage>>())
            {
                onRequesting(requestMessage);
            }
        }
        /// <summary>
        /// 创建连接过滤
        /// </summary>
        /// <param name="client"></param>
        private void OnHttpClientFilter(HttpClient client)
        {
            foreach (var onHttpClient in onHttpClientList ?? new List<Action<HttpClient>>())
            {
                onHttpClient(client);
            }
        } 
        #endregion
    }
}
